using UnityEngine;
using System.Collections;

/// <summary>
/// The enemy aproches to the player
/// and a certain distance, launches its axe
/// </summary>
public class axeEnemy : MonoBehaviour 
{
    public float maxHealth;
    private float health;

    public GameObject myAxe;
    public GameObject player;

    private Transform myTransform;

    private bool hasAxeOnHands;    

    private const float MIN_DISTANCE = 15.0f;
    private const float MOVE_SPEED = 5.0f;
    private const float ROTATION_SPEED = 3.0f;
    private const float NEAR_TO_AXE = 3.5f;

    private const float NEAR_PLAYER = 4.0f;

    private axe ax;

    private const float COOL_DOWN = 1.0f;
    private float attackTimer;

	void Start () 
    {
        myTransform = transform;

        health = maxHealth;

        hasAxeOnHands = true;

        moveAxeToHands();
        myAxe.transform.parent = myTransform;

        ax = (axe)myAxe.GetComponent("axe");
	}
	
    /// <summary>
    /// Decides what to do based on distance to 
    /// player.
    /// </summary>
	void Update () 
    {
        if (!isAlive())
            return;

        if (attackTimer > 0)
            attackTimer -= Time.deltaTime;

        if (distanceTo(player) < NEAR_PLAYER)
        {
            faceTo(player);
            if(facingPlayer())
            {
                if (hasAxeOnHands)
                    throwAxe(player.transform.position);
                else
                    punch();
            }
        }
        else
        {
            if (hasAxeOnHands)
            {
                if (distanceTo(player) > MIN_DISTANCE)
                    moveTo(player);
                else
                {
                    faceTo(player);
                    if (hasAxeOnHands && facingPlayer())
                        throwAxe(player.transform.position);
                }
            }
            else
            {
                if (distanceTo(myAxe) > NEAR_TO_AXE || ax.isMoving())
                    moveTo(myAxe);
                else
                {
                    moveAxeToHands();
                    hasAxeOnHands = true;
                    myAxe.transform.parent = myTransform;
                }
            }
        }
	}

    /// <summary>
    /// Returns if the enemy is facing or not the player
    /// </summary>
    /// <returns>If its facing the player</returns>
    public bool facingPlayer()
    {
        Vector3 dir = (player.transform.position - myTransform.position).normalized;
        float direction = Vector3.Dot(dir, transform.forward);

        return (direction > 0);
    }

    /// <summary>
    /// Throws the axe to the specific location
    /// </summary>
    /// <param name="position">The position to throw the axe</param>
    private void throwAxe(Vector3 position)
    {
        if (attackTimer <= 0)
        {
            attackTimer = COOL_DOWN;
            hasAxeOnHands = false;
            myTransform.DetachChildren();

            ax.moveTo(position);
        }
    }

    /// <summary>
    /// The enemy punches the player
    /// </summary>
    private void punch()
    {
        if (attackTimer <= 0)
        {
            attackTimer = COOL_DOWN;
            print("Attack!! " + Time.time);
        }
    }

    /// <summary>
    /// Calculates the distance 
    /// to the target
    /// </summary>
    /// <returns>The distance</returns>
    private float distanceTo(GameObject target)
    {
        return Vector3.Distance(myTransform.position,
                        target.transform.position);
    }

    /// <summary>
    /// Rotates itself to face the target
    /// </summary>
    private void faceTo(GameObject target)
    {
        Vector3 pos = new Vector3(target.transform.position.x,
                                   myTransform.position.y, 
                                   target.transform.position.z);
        myTransform.rotation = Quaternion.Slerp(myTransform.rotation,
                            Quaternion.LookRotation(pos - myTransform.position),
                            ROTATION_SPEED * Time.deltaTime);
    }

    /// <summary>
    /// Move near the target
    /// </summary>
    private void moveTo(GameObject target)
    {
        faceTo(target);
        Vector3 change = (myTransform.forward * MOVE_SPEED * Time.deltaTime);
        myTransform.position += change;     
    }

    /// <summary>
    /// Substracts from health the ammount of
    /// life given as parameter
    /// </summary>
    /// <param name="ammount">The life to substract</param>
    public void substractToHealth(float ammount)
    {
        health -= ammount;
        if (health < 0)
            health = 0;
    }

    /// <summary>
    /// Cheks if the enemy is still alive
    /// </summary>
    /// <returns>If its alive or not</returns>
    public bool isAlive()
    {
        return (health > 0);
    }

    /// <summary>
    /// Put the axe on the right of the enemy
    /// </summary>
    private void moveAxeToHands()
    {
        myAxe.transform.position = new Vector3(
             myTransform.position.x,
             myTransform.position.y + myTransform.localScale.y / 2 + myAxe.transform.localScale.y / 2,
             myTransform.position.z);
    }
}
